package org.kl.bf.web.basic;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.kl.auditsupervision.entity.fnd.Org;
import org.kl.auditsupervision.service.fnd.OrgService;
import org.kl.bf.entity.basic.DataDetail;
import org.kl.bf.entity.basic.DataRole;
import org.kl.bf.entity.basic.Role;
import org.kl.bf.entity.basic.RunAsConfig;
import org.kl.bf.entity.basic.User;
import org.kl.bf.entity.easyui.EasyuiGrid;
import org.kl.bf.entity.easyui.EasyuiUtils;
import org.kl.bf.service.basic.MenuService;
import org.kl.bf.service.basic.RunAsConfigService;
import org.kl.bf.service.basic.ShiroDbRealm.ShiroUser;
import org.kl.bf.service.basic.UserService;
import org.kl.bf.utils.KLServlets;
import org.kl.bf.web.base.BasicController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springside.modules.security.utils.Digests;
import org.springside.modules.utils.Encodes;
import org.springside.modules.web.MediaTypes;

/**
 * 用户管理
 * 
 * @author Qken
 * @date 2014-3-24
 */
@Controller
@RequestMapping(value = "/basic/user")
public class UserController extends BasicController {

	public static final String HASH_ALGORITHM = "SHA-1";
	public static final int HASH_INTERATIONS = 1024;
	private static final int SALT_SIZE = 8;

	@Autowired
	private UserService userService;
	@Autowired
	private OrgService orgService;
	@Autowired
	private MenuService menuService;
	@Autowired
	private RunAsConfigService runAsConfigService;

	@RequiresPermissions("user:list")
	@RequestMapping(method = RequestMethod.GET)
	public String list() {
		return "basic/userList";
	}

	@RequestMapping(value = "to-updatePassword", method = RequestMethod.GET)
	public String toUpdatePassword() {
		return "basic/updatePasswordList";
	}


	@RequestMapping(value = "to-updatePhone", method = RequestMethod.GET)
	public String toUpdatePhone(Model model) {
		User user=userService.getUser(BasicController.getCurrentUserId());
		model.addAttribute("phone", StringUtils.isNotBlank(user.getPhone())?user.getPhone():"");
		return "basic/updatePhoneList";
	}
	
	@RequiresPermissions("user:list")
	@RequestMapping(value = "dataGrid", produces = MediaTypes.JAVASCRIPT_UTF_8)
	@ResponseBody
	public String dataGrid(@RequestParam(value = "pageNumber", defaultValue = "1") int pageNumber,
			@RequestParam(value = "rows", defaultValue = PAGE_SIZE) int pageSize,
			@RequestParam(value = "sort", defaultValue = "id") String sortType,
			@RequestParam(value = "order", defaultValue = "desc") String orderType, Model model, ServletRequest request) {
		Map<String, Object> searchParams = KLServlets.getParametersStartingWith(request, SEARCH_PREFIX);
		Page<User> users = userService.getUser(searchParams, pageNumber, pageSize, sortType);
		return EasyuiUtils.buildEasyuiGridJsonString(users.getContent(), (int) users.getTotalElements());
	}

	/**
	 * 获取用户根节点菜单
	 * 
	 * @return
	 */
	@RequestMapping(value = "/userMenuRoot", produces = MediaTypes.JAVASCRIPT_UTF_8)
	@ResponseBody
	public String userMenuRoot() {
		if (BasicController.isSysManager()) {
			// 系统管理员则获取所有根节点
			return jsonMapper.toJson(menuService.root());
		} else {
			return jsonMapper.toJson(userService.getUserMenusRoot(getCurrentUserId()));
		}

	}

	/**
	 * 获取用户菜单
	 * 
	 * @return
	 */
	@RequestMapping(value = "/userMenu/{rootId}", produces = MediaTypes.JAVASCRIPT_UTF_8)
	@ResponseBody
	public String userMenu(@PathVariable String rootId) {
		if (BasicController.isSysManager()) {
			// 系统管理员则获取所有菜单
			return jsonMapper.toJson(menuService.tree(rootId));
		} else {
			return jsonMapper.toJson(userService.getUserMenus(getCurrentUserId(), rootId));
		}

	}

	@RequestMapping(value = "favMenus", method = RequestMethod.GET, produces = MediaTypes.JAVASCRIPT_UTF_8)
	@ResponseBody
	public String favMenus(ServletRequest request) {
		return jsonMapper.toJson(userService.getFavMenus(getCurrentUserId()));
	}

	@RequestMapping(value = "addFavMenus/{favMenuId}", method = RequestMethod.GET)
	@ResponseBody
	public String addFavMenus(@PathVariable("favMenuId") String favMenuId) {
		try {
			userService.addFavMenus(getCurrentUserId(), favMenuId);
			return ajaxMsg("添加收藏成功", true, null);
		} catch (Exception e) {
			return ajaxMsg("添加收藏失败!", false, null);
		}
	}

	@RequestMapping(value = "removeFavMenus/{favMenuId}", method = RequestMethod.GET, produces = MediaTypes.JAVASCRIPT_UTF_8)
	@ResponseBody
	public String removeFavMenus(@PathVariable("favMenuId") String favMenuId) {
		try {
			userService.removeFavMenus(getCurrentUserId(), favMenuId);
			return ajaxMsg("删除收藏成功！", true, null);
		} catch (Exception e) {
			return ajaxMsg("删除收藏失败!", false, null);
		}
	}

	@RequiresPermissions("user:update")
	@RequestMapping(value = "update", method = RequestMethod.POST, produces = MediaTypes.JAVASCRIPT_UTF_8)
	@ResponseBody
	public String update(@Valid @ModelAttribute("user") User user, ServletRequest request) {
		try {
			if (!StringUtils.isBlank(user.getPlainPassword())) {
				entryptPassword(user);
			}
			if (user.getEmployee() != null && StringUtils.isBlank(user.getEmployee().getId())) {
				user.setEmployee(null);
			}
			/*if (user.getStaffinfo() != null && StringUtils.isBlank(user.getStaffinfo().getId())) {
				user.setStaffinfo(null);
			}*/
			userService.saveUser(user);
			return ajaxMsg("保存成功!", true, null);
		} catch (Exception e) {
			e.printStackTrace();
			return ajaxMsg("保存失败!", false, null);
		}
	}
	
 
	@RequestMapping(value = "savePhone", method = RequestMethod.POST, produces = MediaTypes.JAVASCRIPT_UTF_8)
	@ResponseBody
	public String savePhone( @RequestParam(value = "phone") String phone,
			@RequestParam(value = "newPassword") String newPassword,
			@RequestParam(value = "newPasswordA") String newPasswordA, ServletRequest request) {
		try {
			
			User user = userService.getUser(BasicController.getCurrentUserId());
			 if (!newPassword.equals(newPasswordA)) {
				return ajaxMsg("输入的二次新密码不一样!", false, null);
			} else {
				byte[] salt = Digests.generateSalt(SALT_SIZE);
				user.setSalt(Encodes.encodeHex(salt));
				byte[] hashPassword = Digests.sha1(newPassword.getBytes(), salt, HASH_INTERATIONS);
				user.setPassword(Encodes.encodeHex(hashPassword));
			}
			 user.setPhone(phone);
			// userService.saveUser(user);
			 return ajaxMsg("保存成功!", true, null);
		} catch (Exception e) {
			e.printStackTrace();
			return ajaxMsg("保存失败!", false, null);
		}
	}

	// 修改密码
	// @RequiresPermissions("user:updatePassword")
	@RequestMapping(value = "updatePassword", method = RequestMethod.POST, produces = MediaTypes.JAVASCRIPT_UTF_8)
	@ResponseBody
	public String updatePassword(@RequestParam(value = "oldPassword") String oldPassword,
			@RequestParam(value = "newPassword") String newPassword,
			@RequestParam(value = "newPasswordA") String newPasswordA, ServletRequest request) {
		try {
			User user = userService.getUser(BasicController.getCurrentUserId());
			String old = Encodes.encodeHex(Digests.sha1(oldPassword.getBytes(), Encodes.decodeHex(user.getSalt()),
					HASH_INTERATIONS));
			if (!old.equals(user.getPassword())) {
				return ajaxMsg("原来的密码不正确!", false, null);
			} else if (!newPassword.equals(newPasswordA)) {
				return ajaxMsg("输入的二次新密码不一样!", false, null);
			} else {
				byte[] salt = Digests.generateSalt(SALT_SIZE);
				user.setSalt(Encodes.encodeHex(salt));
				byte[] hashPassword = Digests.sha1(newPassword.getBytes(), salt, HASH_INTERATIONS);
				user.setPassword(Encodes.encodeHex(hashPassword));
				userService.saveUser(user);
				return ajaxMsg("修改成功!", true, null);
			}

		} catch (Exception e) {
			e.printStackTrace();
			return ajaxMsg("修改失败!", false, null);
		}
	}
	
	@RequiresPermissions("user:delete")
	@RequestMapping(value = "multiDelete", produces = MediaTypes.JAVASCRIPT_UTF_8)
	@ResponseBody
	public String multiDelete(@RequestParam(value = "ids", defaultValue = "") String ids) {
		String msg = "";
		try {
			msg = userService.multiDelete(ids);
		} catch (Exception e) {
			e.printStackTrace();
			return ajaxMsg("删除失败:" + e.getMessage(), false, null);
		}
		return ajaxMsg("删除成功:" + msg, true, null);
	}

	@RequiresPermissions("user:export")
	@RequestMapping(value = "excelExport", produces = MediaTypes.JAVASCRIPT_UTF_8)
	@ResponseBody
	public String excelExport(@RequestParam(value = "pageNumber", defaultValue = "1") int pageNumber,
			@RequestParam(value = "sort", defaultValue = "id") String sortType,
			@RequestParam(value = "order", defaultValue = "desc") String orderType, Model model,
			ServletRequest request, HttpServletResponse response) {
		Map<String, Object> searchParams = KLServlets.getParametersStartingWith(request, SEARCH_PREFIX);
		List<User> users = userService.getAllUser(searchParams, sortType, orderType);
		super.export(User.class, response, users, "用户表");
		return null;
	}

	@RequestMapping(value = "changeRunAs", method = RequestMethod.GET)
	public String changeRunAs() {
		return "basic/changeRunAsList";
	}

	@RequestMapping(value = "runAs", produces = MediaTypes.JAVASCRIPT_UTF_8)
	@ResponseBody
	public String runAs(@RequestParam(value = "userId", defaultValue = "-1") String userId, HttpSession session) {
		if (BasicController.getCurrentUserId().equals(userId)) {
			return ajaxMsg("自己不能切换到自己的身份!", false, null);
		}
		try {
			if (BasicController.isSysManager() || runAsConfigService.exists(userId, BasicController.getCurrentUserId())) {
				User user = userService.getUser(userId);
				Subject subject = SecurityUtils.getSubject();
				String deptId = "";
				String deptName = "";
				String deptCode = "";
				String rootDeptCode = "";
				if(user.getEmployee()!=null && user.getEmployee().getOrg()!=null){
					Org org = user.getEmployee().getOrg();
					deptName = org.getOrgName();
					deptCode = org.getOrgNo();
					deptId=org.getId();
					rootDeptCode = orgService.getOne(org.getRootOrgId()).getOrgNo();
				}
				List<String> roleNoList = new ArrayList<String>();
				for (Role role : user.getRoleSet()) {
					roleNoList.add(role.getRoleNo());
				}
				Map<String, String> dataRoleMap = new HashMap<>();
				for (DataRole dataRole : user.getDataRoleSet()) {
					for (DataDetail dataDetail : dataRole.getDataDetailSet()) {
						if (dataRoleMap.containsKey(dataDetail.getDataType().getCodeName())) {
							if (!dataRoleMap.get(dataDetail.getDataType().getCodeName()).contains(
									dataDetail.getDataName())) {
								String str = dataRoleMap.get(dataDetail.getDataType().getCodeName()) + ","
										+ dataDetail.getDataName();
								dataRoleMap.put(dataDetail.getDataType().getCodeName(), str);
							}
						} else {
							dataRoleMap.put(dataDetail.getDataType().getCodeName(), dataDetail.getDataName());
						}
					}
				}
				subject.runAs(new SimplePrincipalCollection(new ShiroUser(user.getId(), user.getLoginNo(), user
						.getTrueName(), deptId,deptCode, rootDeptCode,deptName, roleNoList, dataRoleMap, user.getSysManager(),
						BasicController.getCurrentUserName(), true), ""));
				session.setAttribute("isRunas", true);
				session.setAttribute("lastName",
						((ShiroUser) subject.getPreviousPrincipals().getPrimaryPrincipal()).name);
				return ajaxMsg("切换身份成功!", true, null);
			} else {
				return ajaxMsg("切换身份失败!", false, null);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return ajaxMsg("切换身份失败!", true, null);
		}
	}

	/**
	 * 切换回上一个身份
	 * 
	 * @return
	 */
	@RequestMapping("/switchBack")
	@ResponseBody
	public String switchBack(HttpSession session) {
		Subject subject = SecurityUtils.getSubject();
		subject.releaseRunAs();
		if (subject.isRunAs() && subject.getPreviousPrincipals() != null
				&& subject.getPreviousPrincipals().getPrimaryPrincipal() != null) {
			session.setAttribute("isRunas", true);
			session.setAttribute("lastName", ((ShiroUser) subject.getPreviousPrincipals().getPrimaryPrincipal()).name);
		} else {
			session.setAttribute("isRunas", false);
			session.setAttribute("lastName", "");
		}
		return ajaxMsg("切换回身份成功!", true, null);
	}

	/**
	 * 获取可委托的身份
	 */
	@RequestMapping(value = "runAsdataGrid", produces = MediaTypes.JAVASCRIPT_UTF_8)
	@ResponseBody
	public String runAsDataGrid(@RequestParam(value = "pageNumber", defaultValue = "1") int pageNumber,
			@RequestParam(value = "rows", defaultValue = PAGE_SIZE) int pageSize,
			@RequestParam(value = "sort", defaultValue = "trueName") String sortType,
			@RequestParam(value = "order", defaultValue = "asc") String orderType, Model model, ServletRequest request) {
		EasyuiGrid grid = new EasyuiGrid();
		if (BasicController.isSysManager()) {// 如果为超级管理员则可以切换所有人身份
			Map<String, Object> searchParams = KLServlets.getParametersStartingWith(request, SEARCH_PREFIX);
			Page<User> users = userService.getUser(searchParams, pageNumber, pageSize, sortType);
			grid.setRows(users.getContent());
			grid.setTotal((int) users.getTotalElements());
		} else {
			Map<String, Object> searchParams = KLServlets.getParametersStartingWith(request, SEARCH_PREFIX);
			String searchName = request.getParameter("search_LIKE_trueName");
			if (StringUtils.isNotBlank(searchName)) {
				searchParams.put("LIKE_fromUser.trueName", searchName);
			}
			searchParams.put("EQ_toUser.id", BasicController.getCurrentUserId());
			searchParams.put("EQ_inUse", "1");
			Page<RunAsConfig> runAsConfigs = runAsConfigService.getRunAsConfig(searchParams, pageNumber, pageSize,
					"id", orderType);
			List<User> userList = new ArrayList<User>();
			for (RunAsConfig rac : runAsConfigs) {
				userList.add(rac.getFromUser());
			}
			grid.setRows(userList);
			grid.setTotal((int) runAsConfigs.getTotalElements());
		}
		String result = jsonMapper.toJson(grid);
		return result;
	}

	/**
	 * 所有RequestMapping方法调用前的Model准备方法, 实现Struts2
	 * Preparable二次部分绑定的效果,先根据form的id从数据库查出Task对象,再把Form提交的内容绑定到该对象上。
	 * 因为仅update()方法的form中有id属性，因此仅在update时实际执行.
	 */
	@ModelAttribute
	public void getUser(@RequestParam(value = "id", defaultValue = "-1") String id, Model model) {
		if (!id.equals("-1")) {
			model.addAttribute("user", userService.getUser(id));
		}
	}

	/**
	 * 设定安全的密码，生成随机的salt并经过1024次 sha-1 hash
	 */
	private void entryptPassword(User user) {
		byte[] salt = Digests.generateSalt(SALT_SIZE);
		user.setSalt(Encodes.encodeHex(salt));

		byte[] hashPassword = Digests.sha1(user.getPlainPassword().getBytes(), salt, HASH_INTERATIONS);
		user.setPassword(Encodes.encodeHex(hashPassword));
	}
	
	
	
	/**
	 * 角色用户查询
	 * 
	 */
	
	@RequestMapping(value = "roles", method = RequestMethod.GET)
	public String roles() {
		return "basic/roleUsersLists";
	}

	 
	@RequestMapping(value = "dataGrids", produces = MediaTypes.JAVASCRIPT_UTF_8)
	@ResponseBody
	public String dataGrids(@RequestParam(value = "roleId", defaultValue = "1") String roleId) {
		List<User>users=userService.findUserListByRoleId(roleId);
		return EasyuiUtils.buildEasyuiGridJsonString(users , (int) users.size());
	}
	
	
	
}
